using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;

namespace Light
{
    /// <summary>
    ///     �洢��GoodsUI��Ҫ�õ��Ķ���
    /// </summary>
    public class ItemsTable : SingletonMono<ItemsTable>
    {
        //������StatusBar����ʾ����������

        private readonly Dictionary<ItemType, AbstractListSO> data = new();
        private readonly string JSONNAME = "Items";

        private GoodsJsonListData listJsonData = new();

        protected override void Awake()
        {
            base.Awake();
            LoadStaticData();

            ////TODO��json���ݱ��ֲ��Գ���
            //listJsonData.data.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 101 });
            //listJsonData.data.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 102 });

            ////listJsonData.data.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 201 });
            ////listJsonData.data.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 202 });

            ////�Ѿ�װ������Ʒ��������
            ////listJsonData.itemsEquipData.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 101 });

            //listJsonData.itemsEquipData.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 201, index = 1 });
            //listJsonData.itemsEquipData.Add(new GoodsJsonData { uId = Guid.NewGuid().ToString(), id = 202, index = 2 });
            //SaveDynamicData();
            LoadDynamicData();
        }

        private void Start()
        {
            Initialize();
        }

        public List<T2> GetData<T1, T2>(ItemType type) where T1 : AbstractListSO, new() where T2 : AbstractItemSO, new()
        {
            if (data.ContainsKey(type))
            {
                data.TryGetValue(type, out var list);
                var result = list as T1;
                return result.GetData<T2>();
            }

            return null;
        }

        public async Task<List<T2>> GetDataAsync<T1, T2>(ItemType type) where T1 : AbstractListSO, new()
            where T2 : AbstractItemSO, new()
        {
            await UniTask.WaitUntil(() => data.Count != 0);

            if (data.ContainsKey(type))
            {
                data.TryGetValue(type, out var list);
                var result = list as T1;
                return result.GetData<T2>();
            }

            return null;
        }

        /// <summary>
        ///     ��ȡgoods�����ѳ��е���Ʒ
        /// </summary>
        /// <returns></returns>
        public IEnumerable<GoodsJsonData> GetGoodsItemJsonData()
        {
            return listJsonData.data;
        }

        /// <summary>
        ///     ��ȡ�Ѿ�װ����Item
        /// </summary>
        /// <returns></returns>
        public IEnumerable<GoodsJsonData> GetGoodsItemEquipJsonData()
        {
            return listJsonData.itemsEquipData;
        }

        /// <summary>
        ///     �첽��
        /// </summary>
        /// <returns></returns>
        public IEnumerable<GoodsJsonData> GetGoodsItemEquipJsonDataAsync()
        {
            return listJsonData.itemsEquipData;
        }

        public void Initialize()
        {
        }

        private void LoadDynamicData()
        {
            listJsonData = JsonManager.Instance.LoadData<GoodsJsonListData>(JSONNAME);
        }

        private void SaveDynamicData()
        {
            JsonManager.Instance.SaveData(listJsonData, JSONNAME);
        }

        private void LoadStaticData()
        {
            //StatusBarPanel��Goods����
            //����
            ResManager.Instance.LoadAsync<WeaponItemListSO>("WeaponItemList",
                list => { data.Add(ItemType.Weapon, list); }, LoadType.AddressAbles);

            //��������
            ResManager.Instance.LoadAsync<PropItemListSO>("PropItemList", list => { data.Add(ItemType.Prop, list); },
                LoadType.AddressAbles);

            //UIManager.Instance.ShowPanel<StatusBarPanel>("StatusBarPanel", E_UI_Layer.Mid);
        }

        /// <summary>
        ///     ��item�б����Ƴ�
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void DeleteJsonDataById(int id)
        {
            var res = listJsonData.data.Find(item => item.id == id);
            if (res == null) return;
            listJsonData.data.Remove(res);

            //����
            SaveDynamicData();
        }

        /// <summary>
        ///     ��itemװ�����Ƴ�
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void DeleteJsonDataEquipById(int id)
        {
            var res = listJsonData.itemsEquipData.Find(item => item.id == id);
            if (res == null) return;
            listJsonData.itemsEquipData.Remove(res);
            //����
            SaveDynamicData();
        }

        public void AddJsonDataToDataByItemId(int id)
        {
            GoodsJsonData data = new() { uId = Guid.NewGuid().ToString(), id = id };
            AddJsonDataToData(data);
        }

        public void AddJsonDataToData(GoodsJsonData data)
        {
            listJsonData.data.Add(data);

            //����
            SaveDynamicData();
        }

        public void AddJsonDataToEquipDataByItemId(int id)
        {
            GoodsJsonData data = new() { uId = Guid.NewGuid().ToString(), id = id };
            AddJsonDataToEquipData(data);
        }

        public void AddJsonDataToEquipData(GoodsJsonData data)
        {
            listJsonData.itemsEquipData.Add(data);

            //����
            SaveDynamicData();
        }

        public GoodsJsonData FindJsonDataById(int id, FunctionBarContentType type)
        {
            if (type == FunctionBarContentType.GoodsItemEuqip)
                return listJsonData.itemsEquipData.Find(item => item.id == id);
            if (type == FunctionBarContentType.GoodsScrollView) return listJsonData.data.Find(data => data.id == id);
            return null;
        }

        public int GetWeaponCount()
        {
            data.TryGetValue(ItemType.Weapon, out var list);
            return list.GetData<WeaponItemSO>().Count;
        }

        public int GetPropCount()
        {
            data.TryGetValue(ItemType.Prop, out var list);
            return list.GetData<PropItemSO>().Count;
        }

        public AbstractItemSO GetItemByTypeAndIndex(ItemType type, int index)
        {
            List<AbstractItemSO> res = new();
            data.TryGetValue(type, out var list);

            if (type == ItemType.Weapon)
                return list.GetData<WeaponItemSO>()[index];

            if (type == ItemType.Prop)
                return list.GetData<PropItemSO>()[index];
            return null;
        }
    }
}